package com.pdemo.core.genericdao;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;

import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.PersistenceContext;




/**
 * @author kcheng
 *
 * @param <T>
 * @param <I>
 */
public class GenericDao<T extends IEntity<I>, I extends Serializable> implements IDao<T, I> {
	


	protected EntityManager entityManager;

	private Class<IEntity<I>> clazz;
	
	private Class keyType;

	/**
	 * Default constructor. Use for extend this class.
	 */
	@SuppressWarnings(value = "unchecked")
	public GenericDao() {
		clazz = (Class<IEntity<I>>) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
		keyType = (Class<IEntity<I>>) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[1]; 
	}

	/**
	 * Set entity manager.
	 * 
	 * @param entityManager  entity manager
	 */
	@PersistenceContext
	public final void setEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
	}

	/**
	 * Get entity manager.
	 * 
	 * @return entity manager
	 */
	public final EntityManager getEntityManager() {
		return entityManager;
	}


	public void delete(I id) throws UnsupportedOperationException {
		delete(load(id));
		
	}
	
	public void delete(T object) throws UnsupportedOperationException {
		entityManager.remove(object);
	}
	
	@SuppressWarnings(value = "unchecked")
	public T get(I id) {
		return (T) entityManager.find(clazz, id);
	}

	public T load(I id) {
		T entity = get(id);
        if (entity == null) {
            throw new EntityNotFoundException("entity " + clazz + "#" + id + " was not found");
        }
        return entity;
	}

	public void save(T object) {
		if (object.getId() != null) {
            entityManager.merge(object);
        } else {
            entityManager.persist(object);
        }
		
	}
	
	public void flush(){
		entityManager.flush();
	}
}
